package com.xh.nci;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class ADOperTest2 {

    public static void main(String args[]) {

        String adminName = "crm_testdev\\crmadmin"; // 注意用户名的写法：domain\User
        String adminPassword = "ncamc@2017"; // 密码
        connect("10.3.3.118:389", adminName, adminPassword);
    }

    /**
     * 使用java连接AD域，获取域账号信息
     *
     * @param username AD域用户名
     * @param password 用户密码
     * @return 域账户List
     * @throws @param url 连接AD域服务器的url,ip + 端口号(默认389)
     */
    private static List connect(String url, String username, String password) {
        List<Map<String, String>> userList = new ArrayList<Map<String, String>>();
        DirContext ctx = null;
        Hashtable<String, String> HashEnv = new Hashtable<String, String>();
        HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple"); // LDAP访问安全级别(none,simple,strong)
        HashEnv.put(Context.SECURITY_PRINCIPAL, username); // AD的用户名
        HashEnv.put(Context.SECURITY_CREDENTIALS, password); // AD的密码
        HashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // LDAP工厂类
        HashEnv.put("com.sun.jndi.ldap.connect.timeout", "20000");// 连接超时设置为20秒
        HashEnv.put(Context.PROVIDER_URL, "ldap://" + url);
        try {
            ctx = new InitialDirContext(HashEnv);// 初始化上下文
            System.out.println("身份验证成功!");
            // 域节点
            String searchBase = "DC=crm_testdev,DC=com";
            // LDAP搜索过滤器类
            String searchFilter = "objectCategory=organizationalUnit"; // user表示用户，group表示组
            // 创建搜索控制器
            SearchControls searchCtls = new SearchControls();
            // 设置搜索等级
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Specify
            // displayName名称(name)，sAMAccountName登录名称(id)，Department部门，Mail邮箱
            String returnedAtts[] = {"displayName", "sAMAccountName", "Department", "Mail"};// 定制返回属性，还有很多属性，可自行百度
            searchCtls.setReturningAttributes(returnedAtts); // 设置返回属性集
            // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
            NamingEnumeration answer = ctx.search(searchBase, searchFilter, searchCtls);// 根据过滤条件查找数据
            System.out.println(answer.toString());
            while (answer.hasMoreElements()) {// 遍历结果集
                System.out.println(1);
                SearchResult sr = (SearchResult) answer.next();
                System.out.println(sr.getName() + sr.getAttributes().toString());
                Attributes Attrs = sr.getAttributes();// 得到域用户属性集
                if (Attrs != null) {
                    try {
                        Map<String, String> m = new HashMap();
                        for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore(); ) {
                            Attribute Attr = (Attribute) ne.next();// 得到下一个属性
                            String key = Attr.getID().toString();
                            // 读取属性值
                            for (NamingEnumeration e = Attr.getAll(); e.hasMore(); ) {
                                String value = e.next().toString();
                                m.put(key, value);
                            }
                        }
                        userList.add(m);
                    } catch (NamingException e) {
                        System.err.println("Throw Exception : " + e);
                    }
                }
                ctx.close();
            }
        } catch (AuthenticationException e) {
            System.out.println("身份验证失败!");
            e.printStackTrace();
        } catch (javax.naming.CommunicationException e) {
            System.out.println("AD域连接失败!");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("身份验证未知异常!");
            e.printStackTrace();
        } finally {
            if (null != ctx) {
                try {
                    ctx.close();
                    ctx = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return userList;
    }
}